/*
@STI LICENSE
(C) 2006-2008 Universit�t Innsbruck.

This file is part of myOntology.

myOntologyis free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

myOntologyis distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with myOntology.  If not, see <http://www.gnu.org/licenses/>.

@STI LICENSE */
package controller.elementMapper;

import java.util.ArrayList;
import java.util.Iterator;

import model.Vocabulary;
import model.dataContainer.OntologyModuleContainer;

import org.apache.log4j.Logger;
import org.openrdf.model.URI;
import org.openrdf.repository.RepositoryConnection;

import controller.HelperFunctions;
import controller.sesameDataConnector.AbstractDataConnector;
import controller.sesameDataConnector.ControllerException;


public class OntologyModuleMapper extends Mapper {
	
	public static Logger logger = Logger.getLogger(OntologyModuleMapper.class);

	protected ArrayList<Exception> exceptionsClassesBelongingToOM = null;
	protected ArrayList<Exception> exceptionsPropertiesBelongingToOM = null;

	protected void addExceptionClassesBelongingToOM( Exception ex ) {
		
		if( this.exceptionsClassesBelongingToOM==null )
			this.exceptionsClassesBelongingToOM = new ArrayList<Exception>();
		this.exceptionOccured = true;
		this.exceptionsClassesBelongingToOM.add( ex );
	}
	public ArrayList<Exception> getExceptionClassesBelongingToOM() {
		return this.exceptionsClassesBelongingToOM;
	}
	
	protected void addExceptionsPropertiesBelongingToOM( Exception ex ) {
		
		if( this.exceptionsPropertiesBelongingToOM==null )
			this.exceptionsPropertiesBelongingToOM = new ArrayList<Exception>();
		this.exceptionOccured = true;
		this.exceptionsPropertiesBelongingToOM.add( ex );
	}
	public ArrayList<Exception> getExceptionsPropertiesBelongingToOM() {
		return this.exceptionsPropertiesBelongingToOM;
	}

	public static OntologyModuleContainer select(URI uri, String lang) {

		OntologyModuleContainer ret = new OntologyModuleContainer();
		
		try {

			ret.setLabel( selectLabel(uri, lang) );
			ret.setComment( selectComment(uri, lang) );
			
			ret.setHasVersionDateTime( selectHasVersionDateTime( uri ) );
			ret.setHasPreviousVersion( AbstractDataConnector.selectObject(uri, Vocabulary.HASPREVIOUSVERSION ) );
			
			ret.setSeeAlso( selectSeeAlso(uri) );
			
			ret.setTranslations( selectTranslation( uri ) );
			
			ret.setSynonyms( selectSynonyms(uri) );
			ret.setTags( selectTags(uri) );
			ret.setFlickrImages( selectImages(uri) );
			ret.setYouTubeVideos( selectVideos(uri) );

			
			ret.setId(uri);
			
		} catch (Exception e) {
			logger.error("Error while selecting uri " + uri + ": ",e);
		}
		
		return ret;
	}
	


	/*
	public static URI copy( URI oldId, String newLabel ) throws Exception {
		
		URI ret = null;
		
		OntologyModuleContainer cont = select( oldId, Vocabulary.ENGLISH );		
		cont.setLabel( newLabel );		
		URI newId = insert( cont, Vocabulary.ENGLISH,
				selectClassesBelongingToOM(oldId),
				selectPropertiesBelongingToOM(oldId) );	
		
		if( newId!=null ) {
						
			// mark the old ID, that it was renamed:				
			AbstractDataConnector.insertTripel( oldId, Vocabulary.WASRENAMEDTO, newId );
			
			ret = newId;
		}
		
		return ret;		
	}
	*/

	/*
	public static URI insert( OntologyModuleContainer data, String lang, ArrayList<URI> newClassesList, ArrayList<URI> newPropertiesList ) throws ControllerException{
		URI ret = null;

		try {
			
			RepositoryConnection con = AbstractDataConnector.getConnection();	
			
			try {
				
				URI id = Mapper.insert(con, data, lang);
				
				//insert all the data of the AbstractElement
				if ( id!=null ) {

					ArrayList<URI> newList = null;
					
					if( newClassesList!=null ) {
						if( newList==null )
							newList = new ArrayList<URI>();
						newList.addAll(newClassesList);
					}

					if( newPropertiesList!=null ) {
						if( newList==null )
							newList = new ArrayList<URI>();
						newList.addAll(newPropertiesList);
					}
					
					if( insertBelongsToOntologyModule( con, id, newList )==true ) {
						con.commit();
						
						ret = id;
					}
					
				}
				
				
				if(id==null) {
					con.rollback();
				}
			} catch( Exception e ) {
				con.rollback();	
				throw e;
			} finally {
				con.close();
			}
		}catch (Exception e) {
			System.out.println("inserting the OM failed: " + e.getMessage());
			if (e instanceof ControllerException)
				throw (ControllerException) e;
		}
		
		return ret;
	}
	*/
	



	/*
	public static boolean update( URI uri, OntologyModuleContainer new_cont, String lang, ArrayList<URI> newClassesList, ArrayList<URI> newPropertiesList ) {
		boolean ret = false;
		
		try {
			RepositoryConnection con = AbstractDataConnector.getConnection();
			try {

				updateComment(con, uri, new_cont.getComment(), lang );
				
				updateSynonyms(con, uri, new_cont.getSynonyms() );
				updateTags( con, uri, new_cont.getTags() );
				updateImages( con, uri, new_cont.getFlickrImages() );
				updateVideos( con, uri, new_cont.getYouTubeVideos() );
				
				updateTranslations( con, uri, new_cont.getTranslations() );
				
				updateSeeAlso( con, uri, new_cont.getSeeAlso() );
				
				updateSubjectsBelongingToOM(con, uri, newClassesList, newPropertiesList);
				
				con.commit();
				ret = true;
			} catch( Exception e ) {
				con.rollback();		
				throw e;			
			} finally {
				con.close();
			}
		}catch (Exception e) {
			System.out.println("error during update of Ontology: " + e.getMessage());
		}
		
		return ret;
	}
	*/
	

	public static ArrayList<URI> selectAll() {
		
		return AbstractDataConnector.selectAllUris(Vocabulary.ONTOLOGYMODULE);		
	}
	
	public static ArrayList<URI> selectDatatypePropertiesOfOM( URI id ) throws Exception {

		return selectPropertiesOfOM( id, Vocabulary.DATATYPEPROPERTY );
	}
	
	public static ArrayList<URI> selectObjectPropertiesOfOM( URI id ) throws Exception {

		return selectPropertiesOfOM( id, Vocabulary.OBJECTPROPERTY );
	}
	
	public static ArrayList<URI> selectPropertiesOfOM( URI id ) throws Exception {
		
		return selectPropertiesOfOM( id, null );
	}

	private static ArrayList<URI> selectPropertiesOfOM( URI id, URI type ) throws Exception {
		ArrayList<URI> ret = null;
		
		URI moreActualVersion = id;
		
		do {

			ArrayList<URI> tmp = AbstractDataConnector.selectPropertiesOfOM( moreActualVersion, type );
		
			if( tmp!=null ) {
				ret = tmp;
				break;
			}		

			moreActualVersion = AbstractDataConnector.selectSubject( Vocabulary.HASPREVIOUSVERSION, moreActualVersion );
			
		} while( moreActualVersion!=null );

		if( ret!=null && ret.get(0).equals(Vocabulary.NULL) )
			ret = null;
	
		return ret;
	}
	
	/**
	 * Selects all classes in the triple <class> <belongsToOM> <id>
	 * @param id the id of the ontology module
	 * @param type the type of the elements, which should belong to the OM-id.
	 */
	public static ArrayList<URI> selectClassesBelongingToOM( URI id ) throws Exception {
		
		ArrayList<URI> ret = null;

		ArrayList<URI> tmp = generateSubjectsOfArchiveableObject( Vocabulary.BELONGSTOONTOLOGYMODULE, id );
		
		// filter by type:
		if( tmp!=null ) {
			Iterator<URI> iter = tmp.iterator();
			while( iter.hasNext() ) {
				URI next = iter.next();
				URI type = AbstractDataConnector.getType( next );
				if( type!=null && type.equals(Vocabulary.CLASS) ){
					
					if( ret==null ){
						ret = new ArrayList<URI>();
					}
					
					ret.add(next);
				}
			}
		}
	
		return ret;		
	}
	
	
	/**
	 * Selects all instances in the triple <class> <belongsToOM> <id>
	 * @param id the id of the ontology module
	 * @param type the type of the elements, which should belong to the OM-id.
	 */
	public static ArrayList<URI> selectInstancesBelongingToOM( URI id ) throws Exception {
		
		ArrayList<URI> ret = null;

		ArrayList<URI> tmp = generateSubjectsOfArchiveableObject( Vocabulary.ISINSTANCEOF, id );
		
		// filter by type:
		if( tmp!=null ) {
			Iterator<URI> iter = tmp.iterator();
			while( iter.hasNext() ) {
				URI next = iter.next();
				URI type = AbstractDataConnector.getType( next );
				if( type!=null && type.equals(Vocabulary.INSTANCE) ){
					
					if( ret==null ){
						ret = new ArrayList<URI>();
					}
					
					ret.add(next);
				}
			}
		}
	
		return ret;		
	}
	
	/**
	 * updates all element-uris in the triple <element> <belongsToOM> <id>
	 * @param id the id of the ontology module
	 */
	public boolean updateClassesBelongingToOM( RepositoryConnection con, URI uri, String entry, String oldtimestamp ) throws Exception {

		boolean ret = false;
		
		entry = trimEntry(entry);
		
		try {
	
			ArrayList<URI> actualEntry = selectClassesBelongingToOM(uri);
			ArrayList<URI> oldEntry = selectClassesBelongingToOM( Mapper.selectVersionUri(uri, oldtimestamp) );
			ArrayList<URI> newEntry = HelperFunctions.extractURIs(entry);

			if( isOneEntryDifferent( actualEntry, newEntry ) ) {
				Mapper.checkIfStoredInMeantime( 
					actualEntry,
					oldEntry );
				
				ArrayList<URI> newList = null;
				
				if( newEntry!=null ) {
					if( newList==null )
						newList = new ArrayList<URI>();
					newList.addAll(newEntry);
				}
				
				/*
				ArrayList<URI> newPropertiesList = selectPropertiesBelongingToOM( uri );
		
				if( newPropertiesList!=null ) {
					if( newList==null )
						newList = new ArrayList<URI>();
					newList.addAll(newPropertiesList);
				}
				*/
		
				ret = OntologyModuleMapper.updateSubjectsBelongingToOM( con, uri, newList );
			}
			else {
				ret = true;
			}
		}
		catch( Exception ex ) {
			this.addExceptionClassesBelongingToOM( ex );
		}
		
		return ret;	
	}
	
	
	public boolean updateInstancesBelongingToOM ( RepositoryConnection con, URI uri, ArrayList<URI> newEntry, String oldtimestamp ) throws Exception {

		boolean ret = false;
		
		try {
	
			ArrayList<URI> actualEntry = selectInstancesBelongingToOM(uri);
			ArrayList<URI> oldEntry = selectInstancesBelongingToOM( Mapper.selectVersionUri(uri, oldtimestamp) );
			
			Mapper.checkIfStoredInMeantime( 
					actualEntry,
					oldEntry );
			
			ArrayList<URI> newList = null;
			
			if( newEntry!=null ) {
				if( newList==null )
					newList = new ArrayList<URI>();
				newList.addAll(newEntry);
			}
			
			/*
			ArrayList<URI> newPropertiesList = selectPropertiesBelongingToOM( uri );
	
			if( newPropertiesList!=null ) {
				if( newList==null )
					newList = new ArrayList<URI>();
				newList.addAll(newPropertiesList);
			}
			*/
	
			ret = OntologyModuleMapper.updateInstancesOfClass( con, uri, newList );
			
			// this will block other threads from overtaking this thread; do not know exectely why but it works...
			Mapper.checkIfStoredInMeantime( 
				actualEntry, 
				selectInstancesBelongingToOM( uri ) );
		}
		catch( Exception ex ) {
			this.addExceptionClassesBelongingToOM( ex );
		}
		
		return ret;	
	}
	
	public boolean updateClassesBelongingToOM( RepositoryConnection con, URI uri, ArrayList<URI> newEntry, String oldtimestamp ) throws Exception {

		boolean ret = false;
		
		try {
	
			ArrayList<URI> actualEntry = selectClassesBelongingToOM(uri);
			ArrayList<URI> oldEntry = selectClassesBelongingToOM( Mapper.selectVersionUri(uri, oldtimestamp) );
			
			Mapper.checkIfStoredInMeantime( 
					actualEntry,
					oldEntry );
			
			ArrayList<URI> newList = null;
			
			if( newEntry!=null ) {
				if( newList==null )
					newList = new ArrayList<URI>();
				newList.addAll(newEntry);
			}
			
			/*
			ArrayList<URI> newPropertiesList = selectPropertiesBelongingToOM( uri );
	
			if( newPropertiesList!=null ) {
				if( newList==null )
					newList = new ArrayList<URI>();
				newList.addAll(newPropertiesList);
			}
			*/
	
			ret = OntologyModuleMapper.updateSubjectsBelongingToOM( con, uri, newList );
			
			// this will block other threads from overtaking this thread; do not know exectely why but it works...
			Mapper.checkIfStoredInMeantime( 
				actualEntry, 
				selectClassesBelongingToOM( uri ) );
		}
		catch( Exception ex ) {
			this.addExceptionClassesBelongingToOM( ex );
		}
		
		return ret;	
	}
	
	/**
	 * Selects all elements in the triple <elements> <belongsToOM> <id>
	 * @param id the id of the ontology module
	 * @param type the type of the elements, which should belong to the OM-id.
	 *//*
	public static ArrayList<URI> selectDatatypePropertiesBelongingToOM( URI id ) throws Exception {
		
		ArrayList<URI> ret = null;
		
		ArrayList<URI> tmp = generateSubjectsOfArchiveableObject( Vocabulary.BELONGSTOONTOLOGYMODULE, id );
		
		// filter by type:
		if( tmp!=null ) {
			Iterator<URI> iter = tmp.iterator();
			while( iter.hasNext() ) {
				URI next = iter.next();
				URI type = AbstractDataConnector.getType( next );
				if( type.equals(Vocabulary.DATATYPEPROPERTY) ){
					
					if( ret==null ){
						ret = new ArrayList<URI>();
					}
					
					ret.add(next);
				}
			}
		}
	
		return ret;				
	}
	/**
	 * Selects all elements in the triple <elements> <belongsToOM> <id>
	 * @param id the id of the ontology module
	 * @param type the type of the elements, which should belong to the OM-id.
	 *//*
	public static ArrayList<URI> selectObjectPropertiesBelongingToOM( URI id ) throws Exception {
		
		ArrayList<URI> ret = null;
		
		ArrayList<URI> tmp = generateSubjectsOfArchiveableObject( Vocabulary.BELONGSTOONTOLOGYMODULE, id );
		
		// filter by type:
		if( tmp!=null ) {
			Iterator<URI> iter = tmp.iterator();
			while( iter.hasNext() ) {
				URI next = iter.next();
				URI type = AbstractDataConnector.getType( next );
				if( type.equals(Vocabulary.OBJECTPROPERTY) ){
					
					if( ret==null ){
						ret = new ArrayList<URI>();
					}
					
					ret.add(next);
				}
			}
		}
	
		return ret;			
	}
	
	/**
	 * Selects all elements in the triple <elements> <belongsToOM> <id>
	 * @param id the id of the ontology module
	 * @param type the type of the elements, which should belong to the OM-id.
	 *//*
	public static ArrayList<URI> selectPropertiesBelongingToOM( URI id ) throws Exception {
		
		ArrayList<URI> ret = null;
		
		ArrayList<URI> tmp = generateSubjectsOfArchiveableObject( Vocabulary.BELONGSTOONTOLOGYMODULE, id );
		
		// filter by type:
		if( tmp!=null ) {
			Iterator<URI> iter = tmp.iterator();
			while( iter.hasNext() ) {
				URI next = iter.next();
				URI type = AbstractDataConnector.getType( next );
				if( type.equals(Vocabulary.DATATYPEPROPERTY) || type.equals(Vocabulary.OBJECTPROPERTY) ){
					
					if( ret==null ){
						ret = new ArrayList<URI>();
					}
					
					ret.add(next);
				}
			}
		}
	
		return ret;		
	}
	/**
	 * updates all element-uris in the triple <element> <belongsToOM> <id>
	 * @param id the id of the ontology module
	 * @param type the type of the elements, which should belong to the OM-id.
	 *//*
	public boolean updatePropertiesBelongingToOM( RepositoryConnection con, URI uri, String entry, String oldtimestamp ) throws Exception {

		boolean ret = false;
		
		entry = trimEntry(entry);
		
		try {
	
			ArrayList<URI> actualEntry = selectPropertiesBelongingToOM(uri);
			ArrayList<URI> oldEntry = selectPropertiesBelongingToOM( Mapper.selectVersionUri(uri, oldtimestamp) );
			ArrayList<URI> newEntry = HelperFunctions.extractURIs(entry);
			
			Mapper.checkIfStoredInMeantime( 
				actualEntry,
				oldEntry );
			
			ArrayList<URI> newList = null;
			ArrayList<URI> newClassesList = selectClassesBelongingToOM(uri);
			
			if( newClassesList!=null ) {
				if( newList==null )
					newList = new ArrayList<URI>();
				newList.addAll(newClassesList);
			}
	
			if( newEntry!=null ) {
				if( newList==null )
					newList = new ArrayList<URI>();
				newList.addAll(newEntry);
			}
	
			ret = OntologyModuleMapper.updateSubjectsBelongingToOM( con, uri, newList );
		}
		catch( Exception ex ) {
			this.addExceptionsPropertiesBelongingToOM( ex );
		}
		
		return ret;	
			
	}
	public boolean updatePropertiesBelongingToOM( RepositoryConnection con, URI uri, ArrayList<URI> newEntry, String oldtimestamp ) throws Exception {

		boolean ret = false;
		
		try {
	
			ArrayList<URI> actualEntry = selectPropertiesBelongingToOM(uri);
			ArrayList<URI> oldEntry = selectPropertiesBelongingToOM( Mapper.selectVersionUri(uri, oldtimestamp) );
			
			Mapper.checkIfStoredInMeantime( 
					actualEntry,
					oldEntry );
			
			ArrayList<URI> newList = null;
			ArrayList<URI> newClassesList = selectClassesBelongingToOM(uri);
			
			if( newClassesList!=null ) {
				if( newList==null )
					newList = new ArrayList<URI>();
				newList.addAll(newClassesList);
			}
	
			if( newEntry!=null ) {
				if( newList==null )
					newList = new ArrayList<URI>();
				newList.addAll(newEntry);
			}
	
			ret = OntologyModuleMapper.updateSubjectsBelongingToOM( con, uri, newList );
		}
		catch( Exception ex ) {
			this.addExceptionsPropertiesBelongingToOM( ex );
		}
		
		return ret;	
			
	}
	*/

	

	/**
	 * Selects all element-uris in the triple <element> <belongsToOM> <id>
	 * @param id the id of the ontology module
	 * @param type the type of the elements, which should belong to the OM-id.
	 */
	private static ArrayList<URI> selectSubjectsBelongingToOM( URI uri ) throws Exception {
		
		ArrayList<URI> ret = generateSubjects( Vocabulary.BELONGSTOONTOLOGYMODULE, uri );
	
		return ret;		
	}	
	/**
	 * updates all element-uris in the triple <element> <belongsToOM> <id>
	 * @param id the id of the ontology module
	 * @param type the type of the elements, which should belong to the OM-id.
	 *//*
	public boolean updateSubjectsBelongingToOM( RepositoryConnection con, URI uri, ArrayList<URI> newClassesList, ArrayList<URI> newPropertiesList ) throws Exception {

		boolean ret = false;
		this.exceptionsSubjectsBelongingToOM = null;
		
		try {
			
			ArrayList<URI> newList = null;
			
			if( newClassesList!=null ) {
				if( newList==null )
					newList = new ArrayList<URI>();
				newList.addAll(newClassesList);
			}
	
			if( newPropertiesList!=null ) {
				if( newList==null )
					newList = new ArrayList<URI>();
				newList.addAll(newPropertiesList);
			}
	
			ret = OntologyModuleMapper.updateSubjectsBelongingToOM( con, uri, newList );
		}
		catch( Exception ex ) {
			this.addExceptionsSubjectsBelongingToOM( ex );
		}
		
		return ret;		
	}
	*/
	

	
	/**
	 * updates all element-uris in the triple <element> <belongsToOM> <id>
	 * @param id the id of the ontology module
	 * @param type the type of the elements, which should belong to the OM-id.
	 */
	private static boolean updateSubjectsBelongingToOM( RepositoryConnection con, URI uri, ArrayList<URI> newSubjects ) throws Exception {

		boolean ret = false;
		
		try {
			
			ArrayList<URI> oldList = selectSubjectsBelongingToOM( uri );
	
			VersioningMapper.archiveRemoveInsertSubject( 
					con, 
					oldList, 
					newSubjects, 
					uri, 
					Vocabulary.BELONGSTOONTOLOGYMODULE );
			ret = true;
		}
		catch( Exception e ) {
			throw e;
		}
		
		return ret;
	}
	
	/**
	 * updates all element-uris in the triple <element> <instanceOfClass> <id>
	 * @param id the id of the ontology module
	 * @param type the type of the elements, which should belong to the OM-id.
	 */
	private static boolean updateInstancesOfClass( RepositoryConnection con, URI uri, ArrayList<URI> newSubjects ) throws Exception {

		boolean ret = false;
		
		try {
			
			ArrayList<URI> oldList = selectInstancesBelongingToOM( uri );
	
			VersioningMapper.archiveRemoveInsertSubject( 
					con, 
					oldList, 
					newSubjects, 
					uri, 
					Vocabulary.ISINSTANCEOF );
			ret = true;
		}
		catch( Exception e ) {
			throw e;
		}
		
		return ret;
	}
	
	
	/**
	 * 
	 * @param subjects
	 * @param object	the URI of the OntologyModule
	 * @return
	 * @throws ControllerException
	 */
	private static boolean insertSubjectsBelongingToOM( RepositoryConnection con, URI uri, ArrayList<URI> newSubjects ) throws Exception {
		boolean ret = false;
		
		try {
			
			if( newSubjects!=null ) {
				Iterator<URI> iter = newSubjects.iterator();
				while( iter.hasNext() ) {

					URI subj = iter.next();
				
					con.add( 
							subj, 
							Vocabulary.BELONGSTOONTOLOGYMODULE, 
							uri );
				}
			}
			ret = true;
	
		}catch (Exception e) {
			logger.error("inserting belongs to ontology module failed: ",e);
			throw e;
		}
	
		return ret;
	}

	public boolean insertClassesBelongingToOM( RepositoryConnection con, URI uri, ArrayList<URI> newClasses ) throws Exception {
		boolean ret = false;
		
		try {
			
			ret = OntologyModuleMapper.insertSubjectsBelongingToOM(con, uri, newClasses);	
		}catch (Exception e) {
			logger.error("inserting belongs to ontology module failed: ",e);
			this.addExceptionClassesBelongingToOM( e );
		}
	
		return ret;
	}
	public boolean insertClassesBelongingToOM( RepositoryConnection con, URI uri, String newEntry ) throws Exception {
		boolean ret = false;
		
		try {
			
			ArrayList<URI> entry = HelperFunctions.extractURIs(newEntry);
			
			ret = OntologyModuleMapper.insertSubjectsBelongingToOM(con, uri, entry);	
		}catch (Exception e) {
			logger.error("inserting belongs to ontology module failed: ",e);
			this.addExceptionClassesBelongingToOM( e );
		}
	
		return ret;
	}
	
	/*
	public boolean insertPropertiesBelongingToOM( RepositoryConnection con, URI uri, ArrayList<URI> newProperties ) throws Exception {
		boolean ret = false;
		
		try {
			
			ret = OntologyModuleMapper.insertSubjectsBelongingToOM(con, uri, newProperties);	
		}catch (Exception e) {
			System.out.println("inserting belongs to ontology module failed: " + e.getMessage());
			this.addExceptionsPropertiesBelongingToOM( e );
		}
	
		return ret;
	}
	
	public boolean insertPropertiesBelongingToOM( RepositoryConnection con, URI uri, String newEntry ) throws Exception {
		boolean ret = false;
		
		try {
			
			ArrayList<URI> entry = HelperFunctions.extractURIs(newEntry);
			
			ret = OntologyModuleMapper.insertSubjectsBelongingToOM(con, uri, entry);
		}catch (Exception e) {
			System.out.println("inserting belongs to ontology module failed: " + e.getMessage());
			this.addExceptionsPropertiesBelongingToOM( e );
		}
	
		return ret;
	}
	*/
	


	// ######################################################################################
	// ######################################################################################
	
	/**
	 * Generates Subjects of Triples with <Archiveable Subjects> <predicate> <object>
	 * @param s	the uri of the subject; can also be a uri of an archived version 
	 * @return
	 */
	private static ArrayList<URI> generateSubjects( URI p, URI o ) throws Exception {
		ArrayList<URI> ret = null;
	
		ret = AbstractDataConnector.selectSubjects( p, o );
		
		URI moreActualVersion = AbstractDataConnector.selectSubject( Vocabulary.HASPREVIOUSVERSION, o );
		
		while( ret==null && moreActualVersion!=null ) {

			ArrayList<URI> tmp = AbstractDataConnector.selectSubjects( p, moreActualVersion );
		
			if( tmp!=null )
				ret = tmp;
			
			moreActualVersion = AbstractDataConnector.selectSubject( Vocabulary.HASPREVIOUSVERSION, moreActualVersion );
		}

		if( ret!=null && ret.get(0).equals(Vocabulary.NULL) )
			ret = null;
	
		return ret;
	}	
	
}
